<?php

namespace app\admin\validate;

use think\Validate;
use app\common\model\CrmFieldConfigs;
use app\common\service\SystemDictService;
use think\facade\Db;

/**
 * 客户验证器 - 动态字段验证
 * 根据CRM字段配置动态生成验证规则
 */
class CustomerValidate extends Validate
{
    /**
     * 动态字段配置缓存
     * @var array
     */
    protected static $fieldConfigs = [];



    /**
     * 构造函数
     */
    public function __construct()
    {
        parent::__construct();
        $this->loadFieldConfigs();
    }

    /**
     * 加载字段配置
     */
    protected function loadFieldConfigs()
    {
        if (empty(self::$fieldConfigs)) {
            $fields = CrmFieldConfigs::whereNull('delete_time')
                ->order('sort', 'asc')
                ->select()
                ->toArray();
            
            self::$fieldConfigs = array_column($fields, null, 'name');
        }
    }

    /**
     * 根据字段配置动态生成验证规则和错误消息
     * @return array [rules => [], messages => []]
     */
    public function generateDynamicRules(): array
    {
        $rules = [];
        $messages = [];
        $regexRules = [];

        $validationRules = SystemDictService::getDictData('validation_rule');
        foreach ($validationRules as $item) {
            $regexRules[$item['value']] = $item;
        }

        foreach (self::$fieldConfigs as $fieldName => $config) {
            $fieldRules = [];
            
            // 跳过已删除的字段
            if (!empty($config['delete_time'])) {
                continue;
            }
            
            // 必填验证
            if ($config['required'] == 1) {
                $fieldRules[] = 'require';
                $messages[$fieldName . '.require'] = $config['label'] . '不能为空';
            }
            
            // 最大长度验证
            if (!empty($config['max_length']) && $config['max_length'] > 0) {
                $fieldRules['max'] = $config['max_length'];
                $messages[$fieldName . '.max'] = $config['label'] . '不能超过' . $config['max_length'] . '个字符';
            }
            
            // 字段类型验证
            $typeRule = $this->getTypeRule($config['type']);
            if ($typeRule) {
                switch ($config['type']) {
                    case 'number':
                        $fieldRules[] = 'number';
                        $messages[$fieldName . '.number'] = $config['label'] . '必须是数字';
                        break;
                    case 'date':
                        $fieldRules[] = 'date';
                        $messages[$fieldName . '.date'] = $config['label'] . '日期格式不正确';
                        break;
                    case 'datetime':
                        $fieldRules['dateFormat'] = 'Y-m-d H:i:s';
                        $messages[$fieldName . '.dateFormat'] = $config['label'] . '日期时间格式不正确';
                        break;
                    default:
                        $fieldRules[] = 'chsDash';
                        $messages[$fieldName . '.chsDash'] = $config['label'] . '格式不正确';
                        break;
                }
            }
            
            // 自定义验证规则
            if (!empty($config['validation'])) {
                if (isset($regexRules[$config['validation']])) {
                    $fieldRules['regex'] = $regexRules[$config['validation']]['remark'];
                    $messages[$fieldName . '.regex'] = $config['label'] . '不符合' . $regexRules[$config['validation']]['label'];
                }
            }
            
            if (!empty($fieldRules)) {
                $rules[$fieldName] = $fieldRules;
            }
        }
        
        return [
            'rules' => $rules,
            'messages' => $messages
        ];
    }


    /**
     * 动态验证所有字段
     * @param array $data 客户数据
     * @param string $scene 验证场景
     * @return array|true 验证结果
     */
    public function validateDynamic(array $data, string $scene = 'save')
    {
        // 生成动态验证规则和错误消息
        $result = $this->generateDynamicRules();
        $rules = $result['rules'];
        $messages = $result['messages'];
        // 创建临时验证器
        $validate = new Validate();
        
        // 根据场景处理必填字段
        if ($scene === 'update') {
            // 更新场景：只验证提供的字段
            $filteredRules = [];
            $filteredMessages = [];
            foreach ($rules as $field => $rule) {
                if (isset($data[$field])) {
                    $filteredRules[$field] = $rule;
                    // 复制对应的错误消息
                    foreach ($messages as $key => $message) {
                        if (strpos($key, $field . '.') === 0) {
                            $filteredMessages[$key] = $message;
                        }
                    }
                }
            }
            $validate->rule($filteredRules);
            $validate->message($filteredMessages);
        } else {
            // 保存场景：验证所有规则
            $validate->rule($rules);
            $validate->message($messages);
        }
        
        // 执行验证
        if (!$validate->check($data)) {
            return $validate->getError();
        }
        
        // 验证字段选项值
        $optionErrors = $this->validateOptions($data);
        if (!empty($optionErrors)) {
            return $optionErrors;
        }
        
        return true;
    }

    /**
     * 验证选项值（select、radio、checkbox等）
     * @param array $data 客户数据
     * @return array 错误信息
     */
    protected function validateOptions(array $data): array
    {
        $errors = [];
        
        foreach (self::$fieldConfigs as $fieldName => $config) {
            // 跳过已删除的字段
            if (!empty($config['delete_time'])) {
                continue;
            }
            
            if (!isset($data[$fieldName]) || empty($data[$fieldName])) {
                continue;
            }
            
            $fieldValue = $data[$fieldName];
            
            // 需要验证选项的字段类型
            $optionTypes = ['select', 'radio', 'checkbox'];
            if (!in_array($config['type'], $optionTypes) || empty($config['options'])) {
                continue;
            }
            
            $options = json_decode($config['options'], true);
            if (!is_array($options)) {
                continue;
            }
            
            $validValues = array_column($options, 'value');
            // 处理不同类型的值
            if ($config['type'] === 'checkbox') {
                // 多选值验证
                if (!is_array($fieldValue)) {
                    $fieldValue = explode(',', $fieldValue);
                }
                if (!empty(array_diff($fieldValue, $validValues))) {
                    $errors[$fieldName] = $config['label'] . '包含无效选项值';
                    break;
                }
            } else {
                // 单选值验证
                if (!in_array($fieldValue, $validValues)) {
                    $errors[$fieldName] = $config['label'] . '选项值无效';
                }
            }
        }
        
        return $errors;
    }

    /**
     * 获取所有字段配置
     * @return array
     */
    public function getAllFieldConfigs(): array
    {
        return self::$fieldConfigs;
    }

    /**
     * 验证必填字段
     * @param array $data 客户数据
     * @return array 缺失的必填字段
     */
    public function validateRequiredFields(array $data): array
    {
        $missing = [];
        
        foreach (self::$fieldConfigs as $fieldName => $config) {
            // 跳过已删除的字段
            if (!empty($config['delete_time'])) {
                continue;
            }
            
            // 检查必填字段
            if ($config['required'] == 1 && (!isset($data[$fieldName]) || empty($data[$fieldName]))) {
                $missing[] = $config['label'];
            }
        }
        
        return $missing;
    }

    /**
     * 验证单个字段值
     * @param string $fieldName 字段名称
     * @param mixed $value 字段值
     * @return array|true 验证结果
     */
    public function validateSingleField(string $fieldName, $value)
    {
        if (!isset(self::$fieldConfigs[$fieldName])) {
            return ['error' => '字段不存在'];
        }
        
        $config = self::$fieldConfigs[$fieldName];
        
        // 构建单个字段的验证规则
        $fieldRules = [];
        $messages = [];
        
        if ($config['required'] == 1) {
            $fieldRules[] = 'require';
            $messages[$fieldName . '.require'] = $config['label'] . '不能为空';
        }
        
        if (!empty($config['max_length']) && $config['max_length'] > 0) {
            $fieldRules['max'] = $config['max_length'];
            $messages[$fieldName . '.max'] = $config['label'] . '不能超过' . $config['max_length'] . '个字符';
        }
        
        // 字段类型验证
        $typeRule = $this->getTypeRule($config['type']);
        if ($typeRule) {
            switch ($config['type']) {
                case 'number':
                    $fieldRules[] = 'number';
                    $messages[$fieldName . '.number'] = $config['label'] . '必须是数字';
                    break;
                case 'date':
                    $fieldRules[] = 'date';
                    $messages[$fieldName . '.date'] = $config['label'] . '日期格式不正确';
                    break;
                case 'datetime':
                    $fieldRules['dateFormat'] = 'Y-m-d H:i:s';
                    $messages[$fieldName . '.dateFormat'] = $config['label'] . '日期时间格式不正确';
                    break;
                case 'checkbox':
                case 'images':
                    $fieldRules[] = 'array';
                    $messages[$fieldName . '.array'] = $config['label'] . '格式不正确';
                    break;
                default:
                    $fieldRules[] = 'chsDash';
                    $messages[$fieldName . '.chsDash'] = $config['label'] . '格式不正确';
                    break;
            }
        }
        
        // 自定义验证规则
        if (!empty($config['validation'])) {
            $customRules = explode('|', $config['validation']);
            foreach ($customRules as $customRule) {
                if (!empty($customRule) && $customRule !== 'require') {
                    if (strpos($customRule, 'between:') === 0) {
                        $betweenValue = str_replace('between:', '', $customRule);
                        $fieldRules['between'] = $betweenValue;
                        $messages[$fieldName . '.between'] = $config['label'] . '必须在' . $betweenValue . '范围内';
                    } elseif (strpos($customRule, 'min:') === 0) {
                        $minValue = str_replace('min:', '', $customRule);
                        $fieldRules['min'] = $minValue;
                        $messages[$fieldName . '.min'] = $config['label'] . '不能小于' . $minValue;
                    } elseif (strpos($customRule, 'max:') === 0) {
                        $maxValue = str_replace('max:', '', $customRule);
                        $fieldRules['max'] = $maxValue;
                        $messages[$fieldName . '.max'] = $config['label'] . '不能大于' . $maxValue;
                    } elseif (strpos($customRule, 'unique:') === 0) {
                        $fieldRules[] = $customRule;
                        $messages[$fieldName . '.unique'] = $config['label'] . '已存在';
                    } elseif ($customRule === 'email') {
                        $fieldRules[] = 'email';
                        $messages[$fieldName . '.email'] = $config['label'] . '格式不正确';
                    } elseif ($customRule === 'mobile') {
                        $fieldRules[] = 'mobile';
                        $messages[$fieldName . '.mobile'] = $config['label'] . '格式不正确';
                    } elseif ($customRule === 'url') {
                        $fieldRules[] = 'url';
                        $messages[$fieldName . '.url'] = $config['label'] . '格式不正确';
                    } elseif (strpos($customRule, 'regex:') === 0) {
                        $regexPattern = str_replace('regex:', '', $customRule);
                        $fieldRules['regex'] = $regexPattern;
                        $messages[$fieldName . '.regex'] = $config['label'] . '格式不正确';
                    } else {
                        $fieldRules[] = $customRule;
                    }
                }
            }
        }
        
        // 选项验证（select、radio、checkbox）
        if (!empty($config['options']) && in_array($config['type'], ['select', 'radio', 'checkbox'])) {
            $options = json_decode($config['options'], true);
            if (is_array($options) && !empty($options)) {
                $validValues = array_column($options, 'value');
                if (!empty($validValues)) {
                    $fieldRules['in'] = implode(',', $validValues);
                    $messages[$fieldName . '.in'] = $config['label'] . '选项无效';
                }
            }
        }
        
        if (empty($fieldRules)) {
            return true;
        }
        
        // 执行验证
        $validate = new Validate();
        $validate->rule([$fieldName => $fieldRules])
                 ->message($messages);
        
        if (!$validate->check([$fieldName => $value])) {
            return ['error' => $validate->getError()];
        }
        
        return true;
    }


}